home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / Ventriloquist / source code / TalkerApp / OTdsp.cp < prev    next >
Encoding:
Text File  |  1997-06-27  |  10.7 KB  |  456 lines  |  [TEXT/CWIE]

  1. //  OTadsp.cp
  2. //#include "Ext4D.h"
  3. #include "OTdsp.h"
  4.  
  5. typedef enum {
  6.     kLoMem = -108,
  7.     kNotSupported = -15000
  8. }    PackageErrs;
  9.  
  10. OSStatus DoNegotiateEOMOption(EndpointRef ep, Boolean enableEOM);
  11. OSStatus DoBind(OTNetConDataHandle netData, int qlen, StringPtr name);
  12. OSStatus DoConnect(OTNetConDataHandle netData);
  13. OSStatus doListen(TEndpoint* ep);
  14. OSErr RegName(OTNetConDataHandle netData, StringPtr name);
  15. void unRegName(OTNetConDataHandle netData);
  16. void strcpyPtoC ( char *dst,  char *src);
  17. void strcatPtoC ( char *dst,  char *src);
  18. short mystrlen ( char *str);
  19. long swapWords (long in);
  20.  
  21. short mystrlen (char *str)
  22. {
  23.     short i = 0;
  24.     for ( i = 0; str[i]!='\0'; i++)
  25.     {    ;
  26.     }
  27. //    i--;
  28.     return i;
  29. }
  30.  
  31. void strcpyPtoC ( char *dst,  char *src)
  32. {
  33.     BlockMove(&src[1],dst, (long)(src[0]) );
  34.     dst[src[0]] = 0;
  35. }
  36.  
  37. void strcatPtoC ( char *dst,  char *src)
  38. {
  39.     short    l;
  40.     l = mystrlen(dst);
  41.     BlockMove(&src[1],&dst[l], (long)(src[0]) );
  42.     dst[l+src[0]] = 0;
  43. }
  44.  
  45. OSErr RegName(OTNetConDataHandle netData, StringPtr name)
  46. {
  47.     OSErr        err = 0;
  48.     OSStatus    oserr = kOTNoError;
  49.     TMapper*    gOTMapper;
  50.     char namebuf[72];
  51.     DDPAddress* epAddr = &(*netData)->addr;
  52.     TRegisterRequest regreq;
  53.     TRegisterReply        regreply;
  54.  
  55.         // set the network address for this name
  56.     regreq.addr.len = sizeof(DDPAddress);
  57.     regreq.addr.buf = (UInt8*)epAddr;
  58.     
  59.         // set up regreply
  60.     regreply.addr.maxlen = 0;
  61.     regreply.addr.buf = nil;
  62.         // put name into address
  63.     namebuf[0] = '\0';
  64.     strcatPtoC( namebuf, (char*) name);
  65.     if(mystrlen(namebuf)) //string is not empty
  66.     {
  67.         strcatPtoC(namebuf, (char*)"\p:NET_4DDB");
  68.         gOTMapper = OTOpenMapper(OTCreateConfiguration(kNBPName), 0, &oserr);
  69.             // create the NBP name string and set the len field for the string
  70.         regreq.name.len = mystrlen(namebuf);    
  71.         regreq.name.maxlen = sizeof(namebuf);
  72.         regreq.name.buf = (UInt8*)namebuf;
  73.         err = gOTMapper->RegisterName( ®req, ®reply);
  74.         err = gOTMapper->Close();
  75.         (*netData)->nameID = regreply.nameid;    
  76.     }
  77.     return err;
  78. }
  79.  
  80. void unRegName(OTNetConDataHandle netData)
  81. {
  82.     OSErr err = 0;
  83.     OSStatus    oserr = kOTNoError;
  84.     TMapper*    gOTMapper;
  85.     
  86.     gOTMapper = OTOpenMapper(OTCreateConfiguration(kNBPName), 0, &oserr);    
  87.     if ((oserr == 0) && ((*netData)->nameID>0))
  88.         {
  89.             gOTMapper->DeleteName((*netData)->nameID);
  90.             (*netData)->nameID = 0;
  91.         }
  92.     if (oserr == 0) err = gOTMapper->Close();
  93. }
  94.  
  95. OSStatus DoNegotiateEOMOption(EndpointRef ep, Boolean enableEOM)
  96.  
  97. {
  98.     UInt8        buf[kOTFourByteOptionSize];    // define buffer for fourByte Option size
  99.     TOption*    opt;                        // option ptr to make items easier to access
  100.     TOptMgmt    req;
  101.     TOptMgmt    ret;
  102.     OSStatus    err;
  103.     Boolean        isAsync = false;
  104.     
  105. //    return( 0L );
  106.     opt = (TOption*)buf;                    // set option ptr to buffer
  107.     req.opt.buf    = buf;
  108.     req.opt.len    = sizeof(buf);
  109.     req.flags    = T_NEGOTIATE;                // negotiate for EOM option
  110.  
  111.     ret.opt.buf = buf;
  112.     ret.opt.maxlen = kOTFourByteOptionSize;
  113.     
  114.     opt->level    = ATK_ADSP;                    // dealing with ADSP
  115.     opt->name    = OPT_ENABLEEOM;
  116.     opt->len    = kOTFourByteOptionSize;
  117.     opt->status = 0;
  118.     *(UInt32*)opt->value = enableEOM;        // set the desired option level, true or false
  119.  
  120.     if (ep->IsSynchronous() == false)            // check whether ep sync or not
  121.     {
  122.         isAsync = true;                        // set flag if async
  123.         ep->SetSynchronous();                    // set endpoint to sync    
  124.         //DebugStr("\pSetSynch;g");
  125.     }
  126.                 
  127.     err = ep->OptionManagement( &req, &ret);
  128.     
  129.     if (isAsync == true)                    // restore ep state if necessary
  130.         {
  131.             ep->SetAsynchronous();
  132.             //DebugStr("\pSet Asynch;g");
  133.         }
  134.  
  135.         // if no error then return the option status value
  136.     if (err == kOTNoError)
  137.     {
  138.         if (opt->status != T_SUCCESS)
  139.             err = opt->status;
  140.         else
  141.             err = kOTNoError;
  142.     }
  143.         
  144.     return err;
  145. }
  146.  
  147. OSStatus DoBind(OTNetConDataHandle netData, int qlen, StringPtr name)
  148. {
  149.     char namebuf[72];
  150.     OSStatus    err;
  151.     DDPNBPAddress    myAddress;            // To set up my address for the bind
  152.     TEndpoint* ep = (*netData)->ep;
  153.  
  154.     myAddress.Init(0, 0, 0);        // Source address & type
  155.     //
  156.     // Create the TBind for the request and return, holding my address
  157.     //
  158.     TBind reqBind, retBind;
  159.     //
  160.     // Set my name into the NBP address, and init the TBind with
  161.     // the address (SetNBPEntity returns the size of the address).
  162.     //
  163.     reqBind.addr.buf    = (UInt8*)&myAddress;
  164.     namebuf[0] = '\0';
  165.     strcatPtoC( namebuf, (char*) name);
  166.     if(mystrlen(namebuf)) //string is not empty
  167.     {
  168.         strcatPtoC(namebuf, (char*)"\p:NET_4DDB");
  169.         reqBind.addr.len    = myAddress.SetNBPEntity(namebuf);
  170.     } else {
  171.         reqBind.addr.len    = 0;
  172.     }
  173.     reqBind.qlen        = qlen;
  174.     
  175.     HLockHi((Handle) netData );
  176.     retBind.addr.buf        = (UInt8*) &(*netData)->addr;
  177.     retBind.addr.maxlen    = sizeof(DDPAddress);
  178.     
  179.     // fprintf(stderr, "Issuing Bind(%d)\n", epNum);
  180.     err = ep->Bind(&reqBind, &retBind);
  181.     HUnlock( (Handle) netData );
  182.     if ( err != kOTNoError )
  183.     {
  184.         // fprintf(stderr, "Bind(%d) fails with %d\n", epNum, err);
  185.         //DebugStr("\pBind Fails.");
  186.     }
  187.     return err;
  188. }
  189.  
  190. OSStatus DoConnect(OTNetConDataHandle netData)
  191. {
  192.     TEndpoint* ep = (*netData)->ep;
  193.     DDPAddress* dest = &(*netData)->addr;
  194.  
  195.     if ( dest == NULL )                    // Need address
  196.     {
  197.         return kLoMem;
  198.     }
  199.     else
  200.     {
  201.         HLockHi( (Handle) netData );
  202.         //
  203.         // Allocate memory to hold a TCall structure and full ddp addresses
  204.         //
  205.         UInt8* p = new UInt8[sizeof(TCall) + kDDPAddressLength];
  206.         
  207.         TCall* reqCall = (TCall*)p;
  208.         
  209.         reqCall->addr.buf    = (UInt8*)(p + sizeof(TCall));
  210.         reqCall->addr.len    = kDDPAddressLength;
  211.         reqCall->opt.len    = 0;
  212.         reqCall->udata.len    = 0;
  213.         ((DDPAddress*)reqCall->addr.buf)->Init(*dest);
  214.         
  215.         OSStatus err = ep->Connect(reqCall, NULL);
  216.         
  217.         delete p;
  218.         HUnlock( (Handle) netData );
  219.         if (( err != kOTNoDataErr ) && ( err != kOTNoError ))
  220.         {
  221.             return err;
  222.         }
  223.         else
  224.         {
  225.             return kOTNoError;
  226.         }
  227.     }
  228. }
  229.  
  230.  
  231. long    OTdspOpen(StringPtr Name, StringPtr Zone)
  232. {
  233.     OSStatus        err;
  234.     long            stop = 0;
  235.     TEndpoint*         ep;
  236.     DDPAddress        addr, addr2;
  237.     NBPAddress        nbpAddr;
  238.     char            namebuf[100];
  239.     Str255            empty = "";
  240.     OTNetConDataHandle    netData = (OTNetConDataHandle) NewHandleClear(sizeof( OTNetConData ));
  241.     
  242.     if( netData == nil )
  243.         return (kLoMem);
  244.     namebuf[0] = '\0';
  245.     strcatPtoC(namebuf,(char*)Name);
  246.     strcatPtoC(namebuf,(char*)"\p:Net_4DDB@");
  247.     strcatPtoC(namebuf,(char*)Zone);
  248.     addr.Init(0, 0, 0);
  249.     addr2.Init(0, 0, 0);
  250.     InitOpenTransport();
  251.     ep = OTOpenEndpoint(OTCreateConfiguration(kADSPName), 0, NULL, &err);
  252.     if ( ep == NULL || err != kOTNoError )    stop = 1;
  253.     (*netData)->ep = ep;
  254.     //if ( stop == 0 ) err = DoNegotiateEOMOption(ep, true);
  255.     if ( stop == 0 ) 
  256.     {
  257.         err = DoBind(netData,0,empty);
  258.         if (err != kOTNoError) stop = 2;
  259.     }
  260.     TBind req, ret;
  261.     if (stop == 0 )
  262.     {
  263.         req.addr.len = nbpAddr.Init(namebuf);
  264.         req.addr.buf = (UInt8*) &nbpAddr;
  265.         ret.addr.buf    = (UInt8*) &addr2;
  266.         ret.addr.maxlen    = sizeof(DDPAddress);
  267.         err = ep->ResolveAddress(&req, &ret,1000L);
  268.     }
  269.     (*netData)->addr = addr2;
  270.     if ( stop == 0 ) err = DoConnect(netData);
  271.     if (err != kOTNoError) stop = 3;
  272.     if (stop != 0) return err;
  273.     else return (long) netData;
  274. }
  275.  
  276.  
  277. long    OTdspListen(StringPtr Name)
  278. {
  279.     OSStatus        err;
  280.     long            stop = 0;
  281.     TEndpoint*         ep;
  282.     DDPAddress        addr;
  283.     Str255            empty = "";
  284.     OTNetConDataHandle    netData = (OTNetConDataHandle) NewHandleClear(sizeof( OTNetConData ));
  285.  
  286.     if( netData == nil )
  287.         return (kLoMem);
  288.  
  289.     InitOpenTransport();
  290.     addr.Init(0, 0, 0);
  291.     ep = OTOpenEndpoint(OTCreateConfiguration(kADSPName), 0, NULL, &err);
  292.     if ( ep == NULL || err != kOTNoError )    stop = 1;
  293.     (*netData)->ep = ep;
  294.     (*netData)->addr = addr;
  295.     if (stop == 0) 
  296.     {
  297.         err = DoBind(netData,1,empty);
  298.         if (err != kOTNoError) stop = 2;
  299.     }
  300.     if (stop == 0) 
  301.     {
  302.         err = RegName(netData,Name);
  303.         if (err != kOTNoError) stop = 3;
  304.     }
  305. //    if (stop == 0) err = DoNegotiateEOMOption(ep, true);    
  306.     switch (stop) {    //intentionally falls thru - cleanup errors
  307.         case 4: 
  308.             ;
  309.         case 3: 
  310.             unRegName(netData);
  311.         case 2: 
  312.             err = ep->Unbind();
  313.         case 1: 
  314.             err = ep->Close();
  315.     }
  316.     if (stop != 0)     return err;
  317.     else return (long) netData;
  318. }
  319.  
  320.  
  321. long    OTClose(long id)
  322. {
  323.     OTNetConDataHandle netData = (OTNetConDataHandle) id;
  324.     TEndpoint*    ep = (*netData)->ep;
  325.     OSStatus    err = ep->SndOrderlyDisconnect();
  326.     err = ep->RcvOrderlyDisconnect();
  327.     if ((*netData)->nameID > 0) unRegName(netData);
  328.     err = ep->Unbind();
  329.     err = ep->Close();
  330.     CloseOpenTransport();
  331.     return err;
  332. }
  333.  
  334. OSStatus    doListen(TEndpoint* ep)
  335. {
  336.     DDPAddress    myAddr;
  337.     OSStatus    err = kOTNoError;
  338.     TCall        lCall;
  339.     lCall.addr.buf        = (UInt8*)&myAddr;
  340.     lCall.addr.maxlen    = sizeof(myAddr);
  341.     lCall.opt.maxlen    = 0;
  342.     lCall.udata.maxlen    = 0;
  343.     myAddr.Init(0,0,0);
  344.     err = ep->Listen(&lCall);
  345.     if ( err == kOTNoDataErr || err == kOTStateChangeErr )
  346.         return kOTNoError;
  347.     if ( err < 0 )
  348.         return err;
  349.  
  350.     lCall.opt.len    = 0;
  351.     lCall.udata.len    = 0;
  352.     lCall.addr.len    = 0;
  353.     err = ep->Accept(ep, &lCall);
  354.     return err;
  355. }
  356.  
  357. long    OTdspStatus(long id)
  358. {
  359.     OTNetConDataHandle netData = (OTNetConDataHandle) id;
  360.     TEndpoint*    ep = (*netData)->ep;
  361.     OSStatus    err = kOTNoError;
  362.     size_t        count;
  363.     OTResult     state;
  364.     
  365.     //DebugStr("\pEnter OTdspStatus;g");
  366.     state = ep->Look();
  367.     switch (state )    {
  368.         case T_LISTEN:
  369.             //DebugStr("\pT_Listen.;g");
  370.             err = doListen(ep);
  371.             unRegName(netData);
  372.             break;
  373.         case T_ORDREL:
  374.             //DebugStr("\pT_Ordrel.;g");
  375.             err = ep->RcvOrderlyDisconnect();
  376.             break;
  377.     }
  378.     state = ep->GetEndpointState();
  379.     switch ( state )    {
  380.         case T_IDLE:
  381.             //DebugStr("\pT_Idle.;g");
  382.             err = 2L;
  383.             break;
  384.         case T_INCON:
  385.             //DebugStr("\pT_Incon.;g");
  386.             err = doListen(ep);
  387.             err = 2L;
  388.             break;
  389.         case T_DATAXFER:
  390.             //DebugStr("\pT_Dataxfer.;g");
  391.             err = ep->CountDataBytes(&count);
  392.             if ((err == kOTNoError) && (count > 0)) 
  393.             {
  394.                 err = 10L;
  395.                 //DebugStr("\pHave Chars;g");
  396.             }
  397.             else err = 4L;
  398.             break;
  399.         case T_INREL:
  400.             //DebugStr("\pT_inrel.;g");
  401.             err = ep->SndOrderlyDisconnect();
  402.             err = 6L;
  403.             break;
  404.     }
  405.     return err;
  406. }
  407.  
  408. long    OTChars(long id)
  409. {
  410.     OTNetConDataHandle netData = (OTNetConDataHandle) id;
  411.     TEndpoint*    ep = (*netData)->ep;
  412.     size_t        count;
  413.     OSStatus    err = ep->CountDataBytes(&count);
  414.     if ((err == kOTNoError) && (count > 0)) return count;
  415.     else return 0;
  416. }
  417.  
  418. long    OTSend(long id, Str31 myText)
  419. {
  420.     OTNetConDataHandle netData = (OTNetConDataHandle) id;
  421.     TEndpoint*    ep = (*netData)->ep;
  422.     short    len = mystrlen((char *)myText);
  423. //    HLockHi((Handle) myText.fData);
  424.     OTResult result = ep->Snd(myText, len, 0);
  425. //    HUnlock((Handle) myText.fData);
  426.     //DebugStr("\pchars sent;g");
  427.     if ( result == len) return 0L;
  428.     else return result;
  429. }
  430.  
  431.  
  432. void    OTRecvText( long id, Str31 myText)    
  433. {
  434.     OTNetConDataHandle netData = (OTNetConDataHandle) id;
  435.     TEndpoint*    ep = (*netData)->ep;
  436.     short    len = 0;
  437.     short    done = 0;
  438.     OTResult    result;
  439.     OTFlags    flags = 0;
  440.     
  441. //    myText.fData = (CharsHandle) NewHandleClear( sizeof( Chars ) );
  442. //    HLockHi( (Handle) myText.fData );
  443.     do    {
  444.         result = ep->Rcv((myText+len), 30, &flags);
  445.         //DebugStr("\pChars received;g");
  446.         if ( result == kOTNoDataErr )    done = 1;
  447.         if ( result == kOTNoDataErr || result == kOTLookErr ||
  448.              result == kOTOutStateErr )
  449.             result = kOTNoError;
  450.         if (result > 0)    len += result;
  451.     }    while ((done == 0) && (len < sizeof(Chars)));
  452. //    myText.fSize = len;
  453. //    HUnlock( (Handle) myText.fData );
  454. //    return (myText);
  455. }    
  456.